home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d3 / dos_edit.arc / DOS-EDIT.ASM next >
Assembly Source File  |  1988-04-20  |  18KB  |  403 lines

  1. ;               DOS-EDIT.ASM -- Resident DOS Command Line Editor
  2. ;               ================================================
  3.  
  4. CSEG            Segment
  5.                 Assume  CS:CSEG
  6.  
  7.                 Org     0080h
  8. KeyboardBuffer  Label   Byte
  9.  
  10.                 Org     0100h
  11. Entry:          Jmp     Initialize
  12.  
  13. ;               All Data
  14. ;               --------
  15.  
  16.                 db      "(C) Copyright 1985 Ziff-Davis Publishing Co."
  17.  
  18. OldInterrupt21  dd      ?               ; Original Interrupt 21 vector
  19. OldInterrupt16  dd      ?               ; Original Interrupt 16 vector
  20. DoingBuffKey    db      0               ; Flag for doing Function call 0Ah
  21. BufferPointer   dw      KeyboardBuffer  ; Pointer to Keyboard Buffer
  22. BufferCounter   db      0               ; Number of characters in buffer
  23. MaxCharCol      db      ?               ; Maximum Character Column on screen
  24. OriginalCursor  dw      ?               ; Place to save cursor on full-screen
  25. InsertOn        db      0               ; Insert mode flag
  26.  
  27. KeyRoutine      dw      Home,Up,PgUp,Dummy,Left,Dummy,Right
  28.                 dw      Dummy,End,Down,PgDn,Insert,Delete
  29.  
  30. ;               New Interrupt 21 (DOS Function Calls)
  31. ;               -------------------------------------
  32.  
  33. NewInterrupt21  Proc    Far
  34.  
  35.                 Mov     CS:[DoingBuffKey],0    ; Turn flag off initially
  36.  
  37.                 Cmp     AH,0Ah                 ; Check if doing buffered input
  38.                 Jz      BufferedInput            
  39.  
  40.                 Jmp     CS:[OldInterrupt21]    ; If not, do regular interrupt
  41.  
  42. BufferedInput:  Mov     CS:[DoingBuffKey],-1   ; If so, turn on flag
  43.  
  44.                 PushF                          ; Simulate regular interrupt
  45.                 Call    CS:[OldInterrupt21]    
  46.  
  47.                 Mov     CS:[DoingBuffKey],0    ; Turn off flag
  48.                 Mov     CS:[BufferCounter],0   ; Re-set character counter
  49.  
  50.                 IRet                           ; Return to user program
  51.  
  52. NewInterrupt21  EndP
  53.  
  54. ;               New Interrupt 16 (BIOS Keyboard Routine)
  55. ;               ----------------------------------------
  56.  
  57. NewInterrupt16  Proc    Far
  58.  
  59.                 Sti                            ; Re-enable interrupts
  60.                 Cmp     CS:[DoingBuffKey],0    ; Check if doing call 0Ah
  61.                 Jz      DoNotIntercept         ; If not, do old interrupt
  62.  
  63.                 Cmp     CS:[BufferCounter],0   ; Check if chars in buffer
  64.                 Jnz     Substitute             ; If so, get them out
  65.  
  66.                 Cmp     AH,0                   ; See if doing a get key
  67.                 Jz      CheckTheKey            ; If so, get the key
  68.  
  69. DoNotIntercept: Jmp     CS:[OldInterrupt16]    ; Otherwise, do old interrupt
  70.  
  71. CheckTheKey:    PushF                          ; Save flags
  72.                 Call    CS:[OldInterrupt16]    ; Do regular interrupt
  73.  
  74.                 Cmp     AX,4800h               ; Check if up cursor
  75.                 Jnz     NotTriggerKey          ; If not, don't bother
  76.  
  77.                 Call    FullScreen             ; Move around the screen
  78.  
  79.                 Cmp     CS:[BufferCounter],0   ; Any chars to deliver?
  80.                 Jz      CheckTheKey            ; If not, get another key
  81.  
  82. ReturnBuffer:   Call    GetBufferChar          ; Otherwise, pull one out
  83.  
  84.                 Inc     CS:[BufferPointer]     ; Kick up the pointer
  85.                 Dec     CS:[BufferCounter]     ; And knock down the counter
  86.  
  87. NotTriggerKey:  IRet                           ; And go back to calling prog
  88.  
  89. ;               Substitute Key from Buffer
  90. ;               --------------------------
  91.  
  92. Substitute:     Cmp     AH,2                   ; See if shift status check
  93.                 Jae     DoNotIntercept         ; If so, can't be bothered
  94.  
  95.                 Cmp     AH,0                   ; See if get a key
  96.                 Jz      ReturnBuffer           ; If so, get the key above
  97.  
  98.                 Call    GetBufferChar          ; Otherwise get a key
  99.                 Cmp     CS:[BufferCounter],0   ; And clear zero flag
  100.  
  101.                 Ret     2                      ; Return with existing flags
  102.  
  103. NewInterrupt16  EndP
  104.  
  105. ;               Get Buffer Character
  106. ;               --------------------
  107.  
  108. GetBufferChar:  Push    BX
  109.                 Mov     BX,CS:[BufferPointer]  ; Get pointer to key buffer
  110.                 Mov     AL,CS:[BX]             ; Get the key
  111.                 Sub     AH,AH                  ; Blank out scan code
  112.                 Pop     BX
  113.                 Ret
  114.  
  115. ;               Full Screen Routine
  116. ;               -------------------
  117.  
  118. FullScreen:     Push    AX                     ; Save all these registers
  119.                 Push    BX
  120.                 Push    CX
  121.                 Push    DX
  122.                 Push    DI
  123.                 Push    DS
  124.                 Push    ES
  125.  
  126.                 Mov     AX,CS                  ; Set AX to this segment
  127.                 Mov     DS,AX                  ; Do DS is this segment
  128.                 Mov     ES,AX                  ; And ES is also
  129.  
  130.                 Assume  DS:CSEG, ES:CSEG       ; Tell the assembler
  131.  
  132.                 Mov     AH,0Fh                 ; Get Video State
  133.                 Int     10h                    ;   through BIOS
  134.                 Dec     AH                     ; Number of columns on screen
  135.                 Mov     [MaxCharCol],AH        ; Save maximum column
  136.                                                ; BH = Page Number throughout
  137.                 Mov     AH,03h                 ; Get cursor in DX
  138.                 Int     10h                    ;   through BIOS
  139.                 Mov     [OriginalCursor],DX    ; And save the cursor position
  140.  
  141.                 Call    Up                     ; Move cursor up
  142.  
  143. MainLoop:       Cmp     DH,Byte Ptr [OriginalCursor + 1]    ; If at line
  144.                 Jz      TermFullScreen         ; stated from, terminate
  145.  
  146.                 Mov     AH,02h                 ; Set cursor from DX
  147.                 Int     10h                    ;   through BIOS
  148.  
  149. GetKeyboard:    Mov     AH,0                   ; Get the next key
  150.                 PushF                          ; By simulating Interrupt 16h
  151.                 Call    CS:[OldInterrupt16]    ;   which goes to BIOS
  152.  
  153.                 Cmp     AL,1Bh                 ; See if Escape key
  154.                 Jz      TermFullScreen         ; If so, terminate full screen
  155.  
  156. ;               Back Space
  157. ;               ----------
  158.  
  159.                 Cmp     AL,08h                 ; See if back space
  160.                 Jnz     NotBackSpace           ; If not, continue test
  161.  
  162.                 Or      DL,DL                  ; Check if cursor at left
  163.                 Jz      MainLoop               ; If so, do nothing
  164.  
  165.                 Dec     DL                     ; Otherwise, move cursor back
  166.                 Call    ShiftLeft              ; And shift line to the left
  167.  
  168.                 Jmp     MainLoop               ; And continue for next key
  169.  
  170. ;               Carriage Return
  171. ;               ---------------
  172.  
  173. NotBackSpace:   Cmp     AL,0Dh                 ; See if Carriage Return
  174.                 Jnz     NotCarrRet             ; If not, continue test
  175.  
  176.                 Call    End                    ; Move line into buffer
  177.  
  178.                 Mov     AL,0Dh                 ; Tack on a Carriage Return
  179.                 Stosb                          ; By writing to buffer
  180.                 Inc     [BufferCounter]        ; One more character in buffer
  181.  
  182.                 Jmp     MainLoop               ; And continue
  183.  
  184. ;               Normal Character
  185. ;               ----------------
  186.  
  187. NotCarrRet:     Cmp     AL,' '                 ; See if normal character
  188.                 Jb      NotNormalChar          ; If not, continue test
  189.  
  190.                 Cmp     [InsertOn],0           ; Check for Insert mode
  191.                 Jz      OverWrite              ; If not, overwrite
  192.  
  193.                 Call    ShiftRight             ; Shift line right for insert
  194.                 Jmp     Short NormalCharEnd    ; And get ready to print
  195.  
  196. OverWrite:      Mov     CX,1                   ; Write one character
  197.                 Mov     AH,0Ah                 ;   by calling BIOS
  198.                 Int     10h
  199.  
  200. NormalCharEnd:  Call    Right                  ; Cursor to right and print
  201.  
  202.                 Jmp     MainLoop               ; Back for another key
  203.  
  204. ;               Cursor Key, Insert, or Delete Subroutine
  205. ;               ----------------------------------------
  206.  
  207. NotNormalChar:  Xchg    AL,AH                  ; Put extended code in AL
  208.                 Sub     AX,71                  ; See if it's a cursor key
  209.                 Jc      GetKeyboard            ; If not, no good
  210.  
  211.                 Cmp     AX,12                  ; Another check for cursor
  212.                 Ja      GetKeyBoard            ; If not, skip it
  213.  
  214.                 Add     AX,AX                  ; Double for index
  215.                 Mov     DI,AX                  ;   into vector table
  216.  
  217.                 Call    [KeyRoutine + DI]      ; Do the routine
  218.  
  219.                 Jmp     MainLoop               ; Back for another key
  220.  
  221. ;               Terminate Full Screen Movement
  222. ;               ------------------------------
  223.  
  224. TermFullScreen: Mov     DX,[OriginalCursor]    ; Set cursor to original
  225.                 Mov     AH,2                   ; And set it
  226.                 Int     10h                    ;   through BIOS
  227.  
  228.                 Pop     ES                     ; Restore all registers
  229.                 Pop     DS
  230.                 Pop     DI
  231.                 Pop     DX
  232.                 Pop     CX
  233.                 Pop     BX
  234.                 Pop     AX
  235.  
  236.                 Ret                            ; And return to New Int. 16h
  237.  
  238. ;               Cursor Movement
  239. ;               ---------------
  240.  
  241. Home:           Mov     DL,Byte Ptr [OriginalCursor]     ; Move cursor to
  242.                 Ret                            ; to original column
  243.  
  244. Up:             Or      DH,DH                  ; Check if at top row
  245.                 Jz      UpEnd                  ; If so, do nothing
  246.                 Dec     DH                     ; If not, decrement row
  247. UpEnd:          Ret
  248.  
  249. PgUp:           Sub     DL,DL                  ; Move cursor to far left
  250.                 Ret
  251.  
  252. Left:           Or      DL,DL                  ; Check if cursor at far left
  253.                 Jnz     GoWest                 ; If not, move it left
  254.                 Mov     DL,[MaxCharCol]        ; Move cursor to right
  255.                 Jmp     Up                     ; And go up one line
  256. GoWest:         Dec     DL                     ; Otherwise, decrement column
  257.                 Ret
  258.  
  259. Right:          Cmp     DL,[MaxCharCol]        ; Check if cursor at far right
  260.                 Jb      GoEast                 ; If not, move it right
  261.                 Sub     DL,DL                  ; Set cursor to left of screen
  262.                 Jmp     Down                   ; And go down one line
  263. GoEast:         Inc     DL                     ; Otherwise, increment column
  264.                 Ret
  265.  
  266. End:            Call    TransferLine           ; Move line to buffer
  267.                 Mov     DX,[OriginalCursor]    ; Set cursor to original
  268.                 Ret
  269.  
  270. Down:           Inc     DH                     ; Move cursor down one row
  271.                 Ret
  272.  
  273. PgDn:           Mov     CL,[MaxCharCol]        ; Get last column on screen
  274.                 Inc     CL                     ; Kick it up by one
  275.                 Sub     CL,DL                  ; Subtract current column
  276.                 Sub     CH,CH                  ; Set top byte to zero
  277.                 Mov     AL,' '                 ; Character to write
  278.                 Mov     AH,0Ah                 ; Write blanks to screen
  279.                 Int     10h                    ;   through BIOS
  280. Dummy:          Ret
  281.  
  282. ;               Insert and Delete
  283. ;               -----------------
  284.  
  285. Insert:         Xor     [InsertOn],-1          ; Toggle the InsertOn flag
  286.                 Ret                            ;   and return
  287.  
  288. Delete:         Call    ShiftLeft              ; Shift cursor line left
  289.                 Ret                            ;   and return
  290.  
  291. ;               Transfer Line on Screen to Keyboard Buffer
  292. ;               ------------------------------------------
  293.  
  294. TransferLine:   Sub     CX,CX                  ; Count characters in line
  295.                 Mov     DI,Offset KeyboardBuffer        ; Place to store 'em
  296.                 Mov     [BufferPointer],DI     ; Save that address
  297.                 Cld                            ; String direction forward
  298.  
  299. GetCharLoop:    Mov     AH,02h                 ; Set Cursor at DX
  300.                 Int     10h                    ;    through BIOS
  301.  
  302.                 Mov     AH,08h                 ; Read Character & Attribute
  303.                 Int     10h                    ;    through BIOS
  304.  
  305.                 Stosb                          ; Save the character
  306.  
  307.                 Inc     CX                     ; Increment the counter
  308.                 Inc     DL                     ; Increment the cursor column
  309.                 Cmp     DL,[MaxCharCol]        ; See if at end of line yet
  310.                 Jbe     GetCharLoop            ; If not, continue
  311.  
  312.                 Dec     DI                     ; Points to end of string
  313.                 Mov     AL,' '                 ; Character to search through
  314.                 Std                            ; Searching backwards
  315.                 Repz    Scasb                  ; Search for first non-blank
  316.                 Cld                            ; Forward direction again
  317.                 Jz      SetBufferCount         ; If all blanks, skip down
  318.  
  319.                 Inc     CL                     ; Number of non-blanks
  320.                 Inc     DI                     ; At last character
  321. SetBufferCount: Inc     DI                     ; After last character
  322.                 Mov     [BufferCounter],CL     ; Save the character count
  323.  
  324.                 Ret                            ; Return from routine
  325.  
  326. ;               Shift Line One Space Right (For Insert)
  327. ;               ---------------------------------------
  328.  
  329. ShiftRight:     Push    DX                     ; Save original cursor
  330.                 Mov     DI,AX                  ; Character to insert
  331. ShiftRightLoop: Call    ReadAndWrite           ; Read character and write
  332.  
  333.                 Inc     DL                     ; Kick up cursor column
  334.                 Cmp     DL,[MaxCharCol]        ; Check if it's rightmost
  335.                 Jbe     ShiftRightLoop         ; If not, keep going
  336.  
  337.                 Pop     DX                     ; Get back original cursor
  338.                 Ret                            ; And return from routine
  339.  
  340. ;               Shift Line One Space Left (For Delete)
  341. ;               --------------------------------------
  342.  
  343. ShiftLeft:      Mov     DI,0020h               ; Blank at end
  344.                 Mov     BL,DL                  ; Save cursor column
  345.                 Mov     DL,[MaxCharCol]        ; Set cursor to end of line
  346.  
  347. ShiftLeftLoop:  Call    ReadAndWrite           ; Read character and write
  348.  
  349.                 Dec     DL                     ; Kick down cursor column
  350.                 Cmp     DL,BL                  ; See if at original yet
  351.                 Jge     ShiftLeftLoop          ; If still higher, keep going
  352.  
  353.                 Inc     DL                     ; Put cursor back to original
  354.                 Ret                            ; And return from routine
  355.  
  356. ;               Read and Write Character for Line Shifts
  357. ;               ----------------------------------------
  358.  
  359. ReadAndWrite:   Mov     AH,2                   ; Set Cursor from DX
  360.                 Int     10h                    ;    through BIOS
  361.  
  362.                 Mov     AH,08h                 ; Read Character and Attribute
  363.                 Int     10h                    ;    through BIOS
  364.  
  365.                 Xchg    AX,DI                  ; Switch with previous char
  366.  
  367.                 Mov     CX,1                   ; One character to write
  368.                 Mov     AH,0Ah                 ; Write charater only
  369.                 Int     10h                    ;    through BIOS
  370.  
  371.                 Ret                            ; Return from routine
  372.  
  373. ;               Initialization on Entry
  374. ;               -----------------------
  375.  
  376. Initialize:     Sub     AX,AX                  ; Make AX equal zero
  377.                 Mov     DS,AX                  ; To point to vector segment
  378.  
  379.                 Les     BX,dword ptr DS:[21h * 4]   ; Get and save Int. 21h
  380.                 Mov     Word Ptr CS:[OldInterrupt21],BX
  381.                 Mov     Word Ptr CS:[OldInterrupt21 + 2],ES
  382.  
  383.                 Les     BX,dword ptr DS:[16h * 4]    ; Get and save Int. 16h
  384.                 Mov     Word Ptr CS:[OldInterrupt16],BX
  385.                 Mov     Word Ptr CS:[OldInterrupt16 + 2],ES
  386.  
  387.                 Push    CS                     ; Restore DS register
  388.                 Pop     DS                     ;    by setting to CS
  389.  
  390.                 Mov     DX,Offset NewInterrupt21
  391.                 Mov     AX,2521h               ; Set new Interrupt 21h
  392.                 Int     21h                    ;    through DOS
  393.  
  394.                 Mov     DX,Offset NewInterrupt16
  395.                 Mov     AX,2516h               ; Set new Interrupt 16h
  396.                 Int     21h                    ;    through DOS
  397.  
  398.                 Mov     DX,Offset Initialize   ; Number of bytes to stay
  399.                 Int     27h                    ; Terminate & Remain Resident
  400.  
  401. CSEG            EndS
  402.                 End     Entry
  403.